/**
 * 
 */
package com.netscenery.yang.model;



import com.netscenery.util.ErrTag;
import com.netscenery.util.QName;



/**
 * @author llly
 *
 */
public class Leaf extends Node {
	private Type type;
	private String units;
	private String defaultValue;
	private boolean isUseDefaultMandatory = true;
	private boolean mandatory;
	private String value;

	
	/**
	 * @return the value
	 */
	public String getValue() {
		return value;
	}
	/**
	 * @param value the value to set
	 */
	public boolean setValue(String value) {
		if(!checkDefaultValue(value)){
			return false;
		}
		this.value = value;
		return true;
	}
	public Leaf(Env env,String name) throws ModelException{
		super(env,name);
	}
	
	
	public boolean isUseDefaultMandatory() {
		return isUseDefaultMandatory;
	}
	/**
	 * @return the type
	 */
	public Type getType() {
		return type;
	}
	/**
	 * @param type the type to set
	 */
	public void setType(Type type) {
		this.type = type;
	}
	
	public Type createType(String builtinType,String derivedType){
		if (null == BuiltinType.getBuiltinType(builtinType)){
			return null;
		}
		Env subEnv = newSubEnv();
		if (null == derivedType){
			return Type.create(subEnv, builtinType);
		}
		Typedef type = null;
		
		QName qname = new QName(derivedType);
		type = Typedef.getDefByQName(env, qname);		
		if (null == type){
			return null;
		}
		
		if (!(type.getType().getBase().getFieldName().equals(builtinType))){
			return null;
		}
		
		return Type.create(subEnv, derivedType);
	}
	
	
	/**
	 * @return the units
	 */
	public String getUnits() {
		return units;
	}
	/**
	 * @param units the units to set
	 */
	public void setUnits(String units) {
		this.units = units;
	}
	/**
	 * @return the defaultValue
	 */
	public String getDefaultValue() {
		return defaultValue;
	}
	/**
	 * @param defaultValue the defaultValue to set
	 */
	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}
	/**
	 * @return the mandatory
	 */
	public boolean isMandatory() {
		return mandatory;
	}
	/**
	 * @param mandatory the mandatory to set
	 */
	public void setMandatory(boolean mandatory) {
		if (this.mandatory == mandatory){
			return;
		}
		this.mandatory = mandatory;
		this.isUseDefaultMandatory = false;
	}
	
	
	
	/**
	 * �жϴ�����Ĭ��ֵ����Ч��
	 * @param value
	 * @return
	 */
	public boolean checkDefaultValue(String value) {
		return this.getType().checkValue(value);
	}
	/* (non-Javadoc)
	 * @see com.netscenery.yang.model.Node#validate()
	 */
	@Override
	public Validator validate() {
		Validator validator = new Validator();
		if (null == type){
			validator.setIsValid(false);
			validator.addMsg(new Message(this,ErrTag.ERROR,"the type of leaf node is mandatory."));
		}
		
		else {
			Validator tValidator = type.validate();
			validator.copy(tValidator);
		}
		/*
		if (null == getMimInfo()){
			return false;
		}*/
		if (this.isKey() && this.isMandatory()){
			
			validator.addMsg(new Message(this,ErrTag.WARNING,"key node should not be mandatory."));
		}
		if (!isNullString(defaultValue)){
			if (this.isMandatory()){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,"mandatory node must have no default value."));
			}
			
			if (this.isKey()){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,"key node must have no default value."));
			}
			if ((null != type) && (type.getBase() == BuiltinType.EMPTY)){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,"node with 'empty' type must have no default value."));
			}
			if (!checkDefaultValue(defaultValue)){
				validator.setIsValid(false);
				validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.INVALID_DEFAULTVALUE));
			}
		}
		else {
			if (!this.isKey() && !this.isMandatory()
					&& ((null != type) && (this.getType().getBase() != BuiltinType.EMPTY)
							&& (this.getType().getBase() != BuiltinType.LEAFREF))){
				if (type.isDerivedType){
					Typedef def = Typedef.getDefByQName(env, new QName(type.getName()));
					if (null == def){
						validator.setIsValid(false);
						validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.COMMON_ERROR));
						return validator;
					}
					
					if (isNullString(def.getDefaultValue())){					
						validator.addMsg(new Message(this,ErrTag.WARNING,"no mandatory node should have default value."));
					}
					else {
						if (!checkDefaultValue(def.getDefaultValue())){
							validator.setIsValid(false);
							validator.addMsg(new Message(this,ErrTag.ERROR,ErrorCode.INVALID_DEFAULTVALUE));
						}
					}
				}
				else {
					validator.addMsg(new Message(this,ErrTag.WARNING,"no mandatory node should have default value."));
				}
				
				
			}
		}
		Validator sValidator = super.validate();
		validator.copy(sValidator);
		return validator;
	}
	@Override
	public void update() {
		// TODO Auto-generated method stub
		
	}

}
